/*
 * :n	,i=n
 * >n	,i+=n
 * <n	,i-=n
 * *n	,d[i]=n
 * +n	,d[i]+=n
 * -n	,d[i]-=n
 * .n	,puts(d[i,i+n])
 * ,n	,gets(d[i,i+n);
 * [	,while(d[i]) {
 * ]	,}
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>

#define MAX_CODE_LEN	100000
#define MAX_DATA_LEN	100000

uint8_t code[MAX_CODE_LEN];
uint8_t datax[MAX_DATA_LEN];
uint8_t data[MAX_DATA_LEN];
uint32_t di;

void
ignore(char **picode)
{
	while (!strchr(":<>=+-.,[]0123456789",**picode)) {
		(*picode)++;
	}
}
uint32_t
dup(char **picode)
{
	uint32_t n=1;
	//ignore(picode);
	if (isdigit(**picode)) {
		n=atoi(*picode);
		while (isdigit(**picode)) {
			(*picode)++;
		}
	}
	return n;
}
void
interpret(char *icode)
{
	uint32_t b, n=1, i;
	uint8_t *w;

	while (*icode) {
		switch (*icode++) {
			case ':':
				n=dup(&icode);
				di=n;
				break;
			case '<':
				n=dup(&icode);
				di-=n;
				break;
			case '>':
				n=dup(&icode);
				di+=n;
				break;
			case '=':
				n=dup(&icode);
				data[di]=n;
				break;
			case '+':
				n=dup(&icode);
				data[di]+=n;
				break;
			case '-':
				n=dup(&icode);
				data[di]-=n;
				break;
			case '.':
				n=dup(&icode);
				for (i=0; i<n; i++) {
					putchar(data[di+i]);fflush(stdout);
				}
				break;
			case ',':
				n=dup(&icode);
				for (i=0; i<n; i++) {
					data[di+i]=getchar();fflush(stdout);
				}
				break;
			case '[':
				for (b=1,w=icode;b&&*icode;icode++)
					b+=*icode=='[',b-=*icode==']';
				if (!b) {
					while (data[di])
						interpret(w);
					break;
				}
				printf("unbalanced brackets!");
				exit(0);
			case ']':
				return;
			default:
				break;
		}
		if (di<0||di>=MAX_DATA_LEN) {
			puts("data index off the range."),exit(0);
		}
	}
}

int
main(int argc, char *argv[])
{
	FILE *fin;
	char *s=code,ch;

	if (fin=fopen(argv[1],"r")) {
		while ((ch=getc(fin))>=0)
			*s++=ch;
		*s=0;
		interpret(code);
	}
	return 0;
}
